﻿using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using ApplLogic.ApplClasses;
using ConnectionObjects;

namespace TCPClient.RequestsToServerHandlers
{
    public class RequestsToServerHandler
    {
        protected NetworkStream m_Stream;
        protected const bool k_HasReturnValue = true;

        public RequestsToServerHandler(){}

        public RequestsToServerHandler(NetworkStream streamRef)
        {
            m_Stream = streamRef;
        }

        public OutConnectionObject GetAllShiftsThatWorkerIsRegisteredTo(string workerId, DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[3];
            paramsArr[0] = workerId;
            paramsArr[1] = startTime;
            paramsArr[2] = endTime;
            InConnectionObject con = new InConnectionObject("GetAllShiftsThatWorkerIsRegisteredTo", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject IsWorkerGotShift(string workerId, DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[3];
            paramsArr[0] = workerId;
            paramsArr[1] = startTime;
            paramsArr[2] = endTime;
            InConnectionObject con = new InConnectionObject("IsWorkerGotShift", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetAllShiftsThatWorkerIsRegisteredToInStep(string workerId, eResult result, DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[4];
            paramsArr[0] = workerId;
            paramsArr[1] = result;
            paramsArr[2] = startTime;
            paramsArr[3] = endTime;
            InConnectionObject con = new InConnectionObject("GetAllShiftsThatWorkerIsRegisteredToInStep", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetAllShiftsThatWorkerAskedWithType(string workerId, eType type, DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[4];
            paramsArr[0] = workerId;
            paramsArr[1] = type;
            paramsArr[2] = startTime;
            paramsArr[3] = endTime;
            InConnectionObject con = new InConnectionObject("GetAllShiftsThatWorkerAskedWithType", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetAllShiftsThatWorkerAsked(string workerId, DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[3];
            paramsArr[0] = workerId;
            paramsArr[1] = startTime;
            paramsArr[2] = endTime;
            InConnectionObject con = new InConnectionObject("GetAllShiftsThatWorkerAsked", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject ShowWorkerDetails(string workerId)
        {
            object[] paramsArr = new object[1];
            paramsArr[0] = workerId;
            InConnectionObject con = new InConnectionObject("ShowWorkerDetails", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject RenterAllRequestsOfWorker(string workerId, DateTime startTime, DateTime endTime, List<ApplSingleRequest> newRequests)
        {
            object[] paramsArr = new object[4];
            paramsArr[0] = workerId;
            paramsArr[1] = startTime;
            paramsArr[2] = endTime;
            paramsArr[3] = newRequests;
            InConnectionObject con = new InConnectionObject("RenterAllRequestsOfWorker", paramsArr, !k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetWorkerStat(DateTime startTime, DateTime endTime, string workerId)
        {
            object[] paramsArr = new object[3];
            paramsArr[0] = startTime;
            paramsArr[1] = endTime;
            paramsArr[2] = workerId;
            InConnectionObject con = new InConnectionObject("GetWorkerStat", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetAllWorkerStatOfWorker(string workerId)
        {
            object[] paramsArr = new object[1];
            paramsArr[0] = workerId;
            InConnectionObject con = new InConnectionObject("GetAllWorkerStatOfWorker", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject ShowShiftDetails(string shiftId)
        {
            object[] paramsArr = new object[1];
            paramsArr[0] = shiftId;
            InConnectionObject con = new InConnectionObject("ShowShiftDetails", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject UpdateWorker(ApplWorker updatedWorker)
        {
            object[] paramsArr = new object[1];
            paramsArr[0] = updatedWorker;
            InConnectionObject con = new InConnectionObject("UpdateWorker", paramsArr, !k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject ShowShiftDetails(DateTime startTime, DateTime endTime)
        {
            object[] paramsArr = new object[2];
            paramsArr[0] = startTime;
            paramsArr[1] = endTime;
            InConnectionObject con = new InConnectionObject("ShowShiftDetails", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetDefaultPeriodBetweenShiftsForRunningAlgo()
        {
            InConnectionObject con = new InConnectionObject("GetDefaultPeriodBetweenShiftsForRunningAlgo", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetMinNumberOfShiftsPerDay()
        {
            InConnectionObject con = new InConnectionObject("GetMinNumberOfShiftsPerDay", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetLenghtOfShift()
        {
            InConnectionObject con = new InConnectionObject("GetLenghtOfShift", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetNumberOfWorkersPerShift()
        {
            InConnectionObject con = new InConnectionObject("GetNumberOfWorkersPerShift", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetNumberOfShiftsPerDay()
        {
            InConnectionObject con = new InConnectionObject("GetNumberOfShiftsPerDay", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }



        public OutConnectionObject GetWorkerById(string workerId)
        {
            object[] paramsArr = new object[1];
            paramsArr[0] = workerId;
            InConnectionObject con = new InConnectionObject("GetWorkerById", paramsArr, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        public OutConnectionObject GetStartTimeOfWork()
        {
            InConnectionObject con = new InConnectionObject("GetStartTimeOfWork", null, k_HasReturnValue);
            sendMessage(con);
            return getMessage();
        }

        protected void sendMessage(InConnectionObject connectionObject)
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(m_Stream, connectionObject);
            m_Stream.Flush();
        }

        protected OutConnectionObject getMessage()
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            OutConnectionObject obj = (OutConnectionObject)binaryFormatter.Deserialize(m_Stream);
            return obj;
        }
    }
}
